﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Asol.Reporting.Support
{
    public partial class Assistant
    {
        #region Práce s PowerBuilder soubory .pbl: čtení obsahu, detekce existence souboru + dataokna, export dataokna do formátu PBL.SRD
        /// <summary>
        /// Vrátí seznam dataoken v dané PBL knihovně.
        /// Pokud neexistuje knihovna PBL, vrací null.
        /// </summary>
        /// <param name="fileNamePbl"></param>
        /// <returns></returns>
        public static List<string> PblLibraryListing(string fileNamePbl)
        {
            return Live._PblLibraryListing(fileNamePbl);
        }
        /// <summary>
        /// Zjistí, zda daná PBL knihovně existuje, a zda v ní existuje dané dataokno.
        /// </summary>
        /// <param name="fileNamePbl"></param>
        /// <param name="dataWindowName"></param>
        /// <returns></returns>
        public static bool PblLibraryExists(string fileNamePbl, string dataWindowName)
        {
            return Live._PblLibraryExists(fileNamePbl, dataWindowName);
        }
        /// <summary>
        /// Vrátí obsah konkrétního dataokna z dané PBL knihovny.
        /// Pokud neexistuje knihovna PBL, vrací empty string.
        /// Pokud v ní neexistuje dataokno, vrací prázdné záhlaví (to je vlastnost PB).
        /// </summary>
        /// <param name="fileNamePbl"></param>
        /// <param name="dataWindowName"></param>
        /// <returns></returns>
        public static string PblLibraryRead(string fileNamePbl, string dataWindowName)
        {
            return Live._PblLibraryRead(fileNamePbl, dataWindowName);
        }
        #region ... private metody
        /// <summary>
        /// Vrátí true, pokud daná knihovna existuje a v ní existuje dané okno.
        /// Tato metoda vyhodí chybu, pokud není dostupná aplikace.
        /// Nevyhodí chybu, pokud neexistuje knihovna PBL nebo dataokno, to vrací false.
        /// </summary>
        /// <param name="fileNamePbl"></param>
        /// <param name="dataWindowName"></param>
        /// <returns></returns>
        private bool _PblLibraryExists(string fileNamePbl, string dataWindowName)
        {
            if (String.IsNullOrEmpty(fileNamePbl)) return false;
            if (!System.IO.File.Exists(fileNamePbl)) return false;
            List<string> dwList = this._PblLibraryListing(fileNamePbl);
            return (dwList != null && dwList.Exists(w => String.Equals(w, dataWindowName, StringComparison.OrdinalIgnoreCase)));
        }
        /// <summary>
        /// Otestuje přítomnost PBL knihovny a dataokna v ní.
        /// Pokud neexistuje aplikace nebo knihovna PBL, hodí chybu.
        /// Pokud existuje, pak vrací true/false podle toho, zda v knihovně najde dané dataokno.
        /// </summary>
        /// <param name="fileNamePbl"></param>
        /// <param name="dataWindowName"></param>
        /// <param name="filePbl"></param>
        /// <param name="libList"></param>
        /// <returns></returns>
        private bool _PblLibraryDwExists(string fileNamePbl, string dataWindowName, out string filePbl, out string libList)
        {
            List<string> dwList = _PblLibraryListing(fileNamePbl, out filePbl, out libList);
            return (dwList != null && dwList.Exists(w => String.Equals(w, dataWindowName, StringComparison.OrdinalIgnoreCase)));
        }
        /// <summary>
        /// Vrací obsah PBL knihovny (seznam dataoken)
        /// </summary>
        /// <param name="fileNamePbl"></param>
        /// <returns></returns>
        private List<string> _PblLibraryListing(string fileNamePbl)
        {
            string filePbl, libList;
            _PblLibraryGetApp(fileNamePbl, out filePbl, out libList);
            return _PblLibraryListing(fileNamePbl, out filePbl, out libList);
        }
        /// <summary>
        /// Vrací obsah PBL knihovny (seznam dataoken)
        /// </summary>
        /// <param name="fileNamePbl"></param>
        /// <param name="filePbl"></param>
        /// <param name="libList"></param>
        /// <returns></returns>
        private List<string> _PblLibraryListing(string fileNamePbl, out string filePbl, out string libList)
        {
            _PblLibraryGetApp(fileNamePbl, out filePbl, out libList);

            string listDtw = Assistant.GetFileNameOnPath(PathType.TemporaryPath, "listing" + (new Random()).Next(1000000, 9999999).ToString() + ".csv");
            string arguments = "LIST \"" + fileNamePbl + "\" \"" + libList + "\" \"" + listDtw + "\" \"\"";

            if (System.IO.File.Exists(listDtw))
                System.IO.File.Delete(listDtw);
            int exitCode = RunProcessSync(filePbl, arguments);
            if (!System.IO.File.Exists(listDtw))
                return null;

            List<string> result = new List<string>();
            string content = System.IO.File.ReadAllText(listDtw, Encoding.UTF8);
            System.IO.File.Delete(listDtw);
            string[] lines = content.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (string line in lines)
            {
                string[] items = line.Split('\t');
                string dataWindowName = items[0];
                if (!String.IsNullOrEmpty(dataWindowName))
                    result.Add(dataWindowName);
            }
            return result;
        }
        /// <summary>
        /// Vrátí obsah konkrétního dataokna z dané PBL knihovny.
        /// Pokud neexistuje knihovna PBL, vrací empty string.
        /// Pokud v ní neexistuje dataokno, vrací prázdné záhlaví (to je vlastnost PB).
        /// </summary>
        /// <param name="fileNamePbl"></param>
        /// <param name="dataWindowName"></param>
        /// <returns></returns>
        private string _PblLibraryRead(string fileNamePbl, string dataWindowName)
        {
            string filePbl, libList;

            if (!_PblLibraryDwExists(fileNamePbl, dataWindowName, out filePbl, out libList))
                throw new UserException("V knihovně %0 neexistuje dataokno %1.", fileNamePbl, dataWindowName);

            string fileSrd = Assistant.GetFileNameOnPath(PathType.TemporaryPath, dataWindowName + ".srd");
            string arguments = "export \"" + fileNamePbl + "\" \"" + libList + "\" \"" + fileSrd + "\" \"" + dataWindowName + "\" \"\"";
            
            if (System.IO.File.Exists(fileSrd))
                System.IO.File.Delete(fileSrd);
            int exitCode = RunProcessSync(filePbl, arguments);
            if (!System.IO.File.Exists(fileSrd))
                throw new UserException("Z knihovny %0 se nepodařilo načíst dataokno %1.", fileNamePbl, dataWindowName);

            string content = System.IO.File.ReadAllText(fileSrd, Encoding.UTF8);
            System.IO.File.Delete(fileSrd);
            // var version = Editor.Data.ReportDocument.DetectDocumentVersion(content);
            return content;
        }
        /// <summary>
        /// Ověří vyplněnost jména a existenci souboru PBL knihovny fileNamePbl (pokud ne, hodí chybu).
        /// </summary>
        /// <param name="fileNamePbl"></param>
        private static void _PblLibraryCheckPbl(string fileNamePbl)
        {
            if (String.IsNullOrEmpty(fileNamePbl))
                throw new UserException("Nelze zpracovat obsah PBL knihovny, soubor nebyl zadán.");
            if (!System.IO.File.Exists(fileNamePbl))
                throw new UserException("Nelze zpracovat obsah PBL knihovny %0, soubor neexistuje.", fileNamePbl);
        }
        /// <summary>
        /// Ověří vyplněnost jména a existenci souboru PBL knihovny fileNamePbl metodou _PblLibraryCheckPbl() (pokud ne, hodí chybu).
        /// Ověří dostupnost aplikace pro práci s PBL soubory (přes _PblLibraryCheckApp())
        /// Do out parametrů vloží fullname souboru dwexpimp.exe a naplní liblist (saverepaspsr_fg.pbd).
        /// </summary>
        /// <param name="fileNamePbl"></param>
        /// <param name="filePbl"></param>
        /// <param name="libList"></param>
        private static void _PblLibraryGetApp(string fileNamePbl, out string filePbl, out string libList)
        {
            _PblLibraryCheckPbl(fileNamePbl);
            _PblLibraryCheckApp(out filePbl);

            string file1 = Assistant.GetFileNameOnPath(PathType.ExecutablePath, "saverepaspsr_fg.pbd");
            if (!System.IO.File.Exists(file1))
                file1 = "";
            
            string pblPath = System.IO.Path.GetDirectoryName(fileNamePbl);
            string file2 = System.IO.Path.Combine(pblPath, "saverepaspsr_fg.pbd");
            if (!System.IO.File.Exists(file2))
                file2 = "";

            libList = file1 + (file1.Length * file2.Length > 0 ? "," : "") + file2;
        }
        /// <summary>
        /// Prověří, zda pro práci s dataokny PowerBuilder máme dostupné potřebné knihovny
        /// </summary>
        private static void _PblLibraryCheckApp(out string filePbl)
        {
            filePbl = _PblLibraryCheckAppOne(PathType.ExecutablePath, "dwexpimp.exe");
            _PblLibraryCheckAppOne(PathType.ExecutablePath, "PBVM110.dll");
            _PblLibraryCheckAppOne(PathType.ExecutablePath, "libjcc.dll");
            _PblLibraryCheckAppOne(PathType.ExecutablePath, "PBSHR110.dll");
            _PblLibraryCheckAppOne(PathType.ExecutablePath, "ATL71.dll");
        }
        /// <summary>
        /// Prověří, zda pro práci s dataokny PowerBuilder máme dostupnou konkrétní knihovnu
        /// </summary>
        /// <param name="pathType"></param>
        /// <param name="name"></param>
        private static string _PblLibraryCheckAppOne(PathType pathType, string name)
        {
            string fullName = Assistant.GetFileNameOnPath(pathType, name);
            if (System.IO.File.Exists(fullName))
                return fullName;
            throw new UserException("Pro práci s reporty typu PBL je zapotřebí knihovna %0 v adresáři aplikace.", name);
        }
        #endregion
        #region ... poznámky
        /*
            Spouští se          dwexpimp.exe
            Dostává argumenty   LIST "C:\Pb7\Reports42\baserep.pbl" "C:\DavidPrac\PbDwExplorer\DataWindowExplorer\DataWindowExplorer\bin\Debug\saverepaspsr_fg.pbd" "C:\Users\David.Janacek\AppData\Local\Temp\aux140602124010" ""
                                export "C:\Pb7\Reports42\baserep.pbl" "C:\DavidPrac\PbDwExplorer\DataWindowExplorer\DataWindowExplorer\bin\Debug\saverepaspsr_fg.pbd" "C:\Pb7\Reports42\dw_nested_nazev_kategorie.SRD" "dw_nested_nazev_kategorie" ""
                                export "c:\Pb7\Reports42\mzdyrep.pbl" "C:\Users\David.Janacek\AppData\Local\Temp\saverepaspsr_fg.pbd" "C:\Users\David.Janacek\AppData\Local\Temp\dw_cerpani_min_rok.srd" ""
                                export "c:\Pb7\Reports42\mzdyrep.pbl" "C:\Users\David.Janacek\AppData\Local\Temp\saverepaspsr_fg.pbd" "C:\Users\David.Janacek\AppData\Local\Temp\dw_cerpani_min_rok.srd" "dw_cerpani_min_rok" ""


            tedy příkaz a soubory: vstupní PBL; nějaký pracovní PBL (_AdditionalLiblistComplete), výstupní (do něj se píše LISTing, exportuje se atd), as "".

            _AdditionalLiblistComplete si vytvoří sám ?.


 Potřebujeme soubory:
dwexpimp.exe
PBVM110.dll
libjcc.dll
PBSHR110.dll
ATL71.dll             -> a projde LISTing i EXPORT



Listing:
UTF8
Řádky oddělené 0x0A (nikoli CrLf)
Položky oddělené 0x09 (TAB)
Sloupce: NázevDW tab Datum (16.9.2008 14:56:33) tab Komentář


addLibList může obsahovat více PBL:
C:\DavidPrac\PbDwExplorer\DataWindowExplorer\DataWindowExplorer\bin\Debug\saverepaspsr_fg.pbd,C:\Pb7\Reports42\majetcizi.pbl,


LIST "C:\Pb7\Reports42\mfrrep.pbl" "C:\DavidPrac\PbDwExplorer\DataWindowExplorer\DataWindowExplorer\bin\Debug\saverepaspsr_fg.pbd,C:\Pb7\Reports42\majetcizi.pbl," "C:\Users\David.Janacek\AppData\Local\Temp\aux140602124010" ""


*/
        #endregion
        #endregion
    }
}
